using System;
using System.Reflection;
using System.Collections.Generic;
using System.Web.UI.WebControls;

using SBPweb.Data;

namespace SBPweb.Controls.Web
{

	/// <summary>
	/// This class compares entities
	/// </summary>
	/// <typeparam name="T">Entity type</typeparam>
	public class EntityGenericComparer<T> : IComparer<T> where T : Entity
	{

		#region Private members

		private string mExp;
		private int mSgn;
		private PropertyInfo mPI;
		private MethodInfo mMI;

		#endregion

		#region Constructor logic

		/// <summary>
		/// Initializes a new EntityGenericComparer instance
		/// </summary>
		/// <param name="expression">Compare expression</param>
		/// <param name="direction">Direction of sorting</param>
		public EntityGenericComparer(string expression, SortDirection direction)
		{
			mExp = expression;
			mSgn = (direction == SortDirection.Ascending) ? 1 : -1;
		}

		#endregion

		#region IComparer Members

		/// <summary>
		/// This method compares two entities
		/// </summary>
		/// <param name="x">An entity instance</param>
		/// <param name="y">An entity instance</param>
		/// <returns></returns>
		public int Compare(T x, T y)
		{
			if (x == null && y == null)
			{
				return 0;
			}

			if (mPI == null)
			{
				mPI = x.GetType().GetProperty(mExp);
			}
			if (mMI == null)
			{
				mMI = mPI.PropertyType.GetMethod("CompareTo", new Type[] { mPI.PropertyType });
			}

			object oX = mPI.GetValue(x, null);
			object oY = mPI.GetValue(y, null);

			if (mMI == null)
			{
				mMI = oX.GetType().GetMethod("CompareTo", new Type[] { mPI.GetType() });
			}

			if (oX == null && oY != null)
			{
				return -1 * mSgn;
			}
			if (oY == null && oX != null)
			{
				return 1 * mSgn;
			}

			if (oX == null && oY == null)
			{
				return 0;
			}

			return Convert.ToInt32(mMI.Invoke(oX, new object[] { oY })) * mSgn;
		}

		#endregion

	}
}
